package com.kfyty.hot.deploy.controller;

import com.kfyty.loveqq.framework.boot.context.ContextRefresher;
import com.kfyty.loveqq.framework.core.autoconfig.annotation.Value;
import com.kfyty.loveqq.framework.core.lang.JarIndexClassLoader;
import com.kfyty.loveqq.framework.core.utils.ClassLoaderUtil;
import com.kfyty.loveqq.framework.core.utils.IOUtil;
import com.kfyty.loveqq.framework.web.core.annotation.RequestMapping;
import com.kfyty.loveqq.framework.web.core.annotation.RestController;
import com.kfyty.loveqq.framework.web.core.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

@RestController
@RequestMapping(value = "/hot", expose = true)
public class HotDeployController {
    /**
     * 这个值是打包后的 boot-lib 文件夹路径，里面是依赖包
     */
    @Value("${bootLibPath:C:\\Users\\admin\\Desktop\\boot-lib}")
    private String bootLibPath;

    /**
     * 热部署，覆盖 boot-lib 文件夹下的依赖包，然后进行热部署
     *
     * @param jars jar 包，命名必须和已有的库名称相同
     */
    public String deploy(List<MultipartFile> jars) throws Exception {
        // 构建的 JarFile
        List<File> jarFiles = new LinkedList<>();

        // 覆盖到依赖 jar 包
        for (MultipartFile jar : jars) {
            File file = new File(this.bootLibPath, jar.getOriginalFilename());
            try (ZipInputStream in = new JarInputStream(jar.getInputStream());
                 ZipOutputStream out = new JarOutputStream(new FileOutputStream(file))) {
                IOUtil.copy(in, out, "");
                jarFiles.add(file);
            }
        }

        // 部署到框架 ClassLoader
        JarIndexClassLoader classLoader = ClassLoaderUtil.getIndexedClassloader();

        classLoader.deploy(jarFiles);

        // 刷新上下文
        ContextRefresher.refresh();

        return "ok";
    }
}
